package org.byd.dmsja.interceptors;

import com.auth0.jwt.exceptions.AlgorithmMismatchException;
import com.auth0.jwt.exceptions.InvalidClaimException;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.byd.dmsja.utils.JWTUtils;
import org.springframework.http.HttpMethod;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.HashMap;
import java.util.Map;


/**
 * Created by Chilly Cui on 2020/9/9.
 */
@CrossOrigin
@Slf4j
public class JWTInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {

        //表示接受任意域名的请求,也可以指定域名
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));

        //该字段可选，是个布尔值，表示是否可以携带cookie
        response.setHeader("Access-Control-Allow-Credentials", "true");

        response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");

        response.setHeader("Access-Control-Allow-Headers", "*");


        //这里可以不加，但是其他语言开发的话记得处理options请求
        /**
         * 非简单请求是对那种对服务器有特殊要求的请求，
         * 比如请求方式是PUT或者DELETE，或者Content-Type字段类型是application/json。
         * 都会在正式通信之前，增加一次HTTP请求，称之为预检。浏览器会先询问服务器，当前网页所在域名是否在服务器的许可名单之中，
         * 服务器允许之后，浏览器会发出正式的XMLHttpRequest请求
         */
        if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
            return true;
        }

        //获取请求头中的令牌
        String token = request.getHeader("token");
//        log.info("当前token为：{}", token);
        System.out.println("当前token为：" + token);

        Map<String, Object> map = new HashMap<>();
        try {
            JWTUtils.verify(token);
            return true;
        } catch (SignatureVerificationException e) {
            e.printStackTrace();
            map.put("errMsg", "签名不一致");
        } catch (TokenExpiredException e) {
            e.printStackTrace();
            map.put("errMsg", "令牌过期");
        } catch (AlgorithmMismatchException e) {
            e.printStackTrace();
            map.put("errMsg", "算法不匹配");
        } catch (InvalidClaimException e) {
            e.printStackTrace();
            map.put("errMsg", "失效的payload");
        } catch (Exception e) {
            e.printStackTrace();
            map.put("errMsg", "token无效");
        }
        map.put("state", false);
        //响应到前台: 将map转为json
        String json = new ObjectMapper().writeValueAsString(map);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(json);
        return false;
    }
}
